package com.example.leetcode.prcatice;

/**
 * 设计实现双端队列。
 *
 * 实现 MyCircularDeque 类:
 *
 * MyCircularDeque(int k) ：构造函数,双端队列最大为 k 。
 * boolean insertFront()：将一个元素添加到双端队列头部。 如果操作成功返回 true ，否则返回 false 。
 * boolean insertLast() ：将一个元素添加到双端队列尾部。如果操作成功返回 true ，否则返回 false 。
 * boolean deleteFront() ：从双端队列头部删除一个元素。 如果操作成功返回 true ，否则返回 false 。
 * boolean deleteLast() ：从双端队列尾部删除一个元素。如果操作成功返回 true ，否则返回 false 。
 * int getFront() )：从双端队列头部获得一个元素。如果双端队列为空，返回 -1 。
 * int getRear() ：获得双端队列的最后一个元素。 如果双端队列为空，返回 -1 。
 * boolean isEmpty() ：若双端队列为空，则返回 true ，否则返回 false  。
 * boolean isFull() ：若双端队列满了，则返回 true ，否则返回 false 。
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/design-circular-deque
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class MyCircularDeque {

    private MyNode firstNode = null;

    private MyNode lastNode = null;

    private int size = 0;

    private int max = 0;

    public MyCircularDeque(int k) {
        max = k;
    }

    public boolean insertFront(int value) {
        if (size == max) {
            return false;
        }
        MyNode myNode = new MyNode(value);
        if (size != 0) {
            firstNode.pre = myNode;
            myNode.next = firstNode;
        } else {
            lastNode = myNode;
        }
        firstNode = myNode;
        size++;
        return true;
    }

    public boolean insertLast(int value) {
        if (size == max) {
            return false;
        }
        MyNode node = new MyNode(value);
        if (size != 0) {
            lastNode.next = node;
            node.pre = lastNode;
        } else {
            firstNode = node;
        }
        lastNode = node;
        size++;
        return true;
    }

    public boolean deleteFront() {
        if (size == 0) {
            return false;
        }
        MyNode next = firstNode.next;
        if (next != null) {
            firstNode.next = null;
            next.pre = null;
        }
        firstNode = next;
        size--;
        return true;
    }

    public boolean deleteLast() {
        if (size == 0) {
            return false;
        }
        MyNode last = lastNode.pre;
        if (last != null) {
            last.next = null;
            lastNode.pre = null;
        }
        lastNode = last;
        size--;
        return true;
    }

    public int getFront() {
        if (size == 0) {
            return -1;
        }
        return firstNode.value;
    }

    public int getRear() {
        if (size == 0) {
            return -1;
        }
        return lastNode.value;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public boolean isFull() {
        return size == max;
    }

    class MyNode {
        private int value;

        private MyNode next;

        private MyNode pre;

        public MyNode(int value) {
            this.value = value;
        }

        public MyNode getNext() {
            return next;
        }

        public void setNext(MyNode next) {
            this.next = next;
        }

        public MyNode getPre() {
            return pre;
        }

        public void setPre(MyNode pre) {
            this.pre = pre;
        }
    }

    public static void main(String[] args) {
        MyCircularDeque myCircularDeque = new MyCircularDeque(77);
        myCircularDeque.insertFront(89);
        System.out.println(myCircularDeque.getRear());
        myCircularDeque.deleteLast();
        System.out.println(myCircularDeque.getRear());
        myCircularDeque.insertFront(1);
        System.out.println(myCircularDeque.getRear());
    }
}
